<!--
 * @Date: 2023-04-13 15:38:00
 * @LastEditTime: 2023-09-25 17:37:52

 * 介绍:
-->
<script lang="ts" setup>
import type {
  FieldType,
  FieldClearTrigger,
  FieldTextAlign,
  FieldFormatTrigger,
  FieldAutosizeConfig,
  FieldRule,
} from "vant";
import omit from "lodash/omit";
import { filterObject } from "@@/utils/tools/object";
import { BorderStyle, BorderMode } from "@@/components/types";

const props = withDefaults(
  defineProps<{
    modelValue?: StrNumber;
    label?: string;
    name?: string;
    type?: FieldType;
    size?: "large";
    maxlength?: StrNumber;
    placeholder?: string;
    borderMode?: BorderMode[] | BorderMode;
    borderColor?: string;
    borderStyle?: BorderStyle;
    borderWidth?: string;
    disabled?: boolean;
    readonly?: boolean;
    colon?: boolean;
    required?: boolean;
    center?: boolean;
    clearable?: boolean;
    clearIcon?: string;
    /**显示清除图标的时机 */
    clearTrigger?: FieldClearTrigger;
    /**	是否开启点击反馈 */
    clickable?: boolean;
    /**是否展示右侧箭头并开启点击反馈 */
    isLink?: boolean;
    /**是否自动聚焦，iOS 系统不支持该属性 */
    autofocus?: boolean;
    /**是否显示字数统计，需要设置 maxlength 属性 */
    showWordLimit?: boolean;
    /**是否将输入内容标红 */
    error?: string;
    /**错误提示文案对齐方式，可选值为 center right */
    errorMessage?: FieldTextAlign;
    /**格式化函数 */
    formatter?: (val: string) => string;
    /**格式化触发时机 */
    formatTrigger?: FieldFormatTrigger;
    /**箭头方向 */
    arrowDirection?: "left" | "up" | "down";
    /**左侧文本额外类名 */
    labelClass?: string | Array<string> | object;
    /**左侧文本宽度，默认单位为 px */
    labelWidth?: StrNumber;
    labelAlign?: FieldTextAlign;
    inputAlign?: FieldTextAlign;
    /**是否自适应内容高度，只对 textarea 有效，可传入对象,如 { maxHeight: 100, minHeight: 50 }，单位为px */
    autosize?: boolean | FieldAutosizeConfig;
    leftIcon?: string;
    rightIcon?: string;
    iconPrefix?: string;
    /**表单验证规则 */
    rules?: FieldRule[];
    /**HTML 原生属性，用于控制自动完成功能 */
    autocomplete?: string;
    /**HTML 原生属性，用于控制回车键样式，此 API 仅在部分浏览器支持 */
    enterkeyhint?: string;
  }>(),
  {
    type: "text",
    borderColor: "var(--C-T1-O1)",
    borderStyle: "solid",
    borderWidth: "1rem",
  }
);
const emit = defineEmits<{
  (e: "update:model-value", v: string): void;
  (e: "focus", v: Event): void;
  (e: "blur", v: Event): void;
  (e: "clear", v: MouseEvent): void;
  (e: "click", v: MouseEvent): void;
  (e: "click-input", v: MouseEvent): void;
  (e: "click-left-icon", v: MouseEvent): void;
  (e: "click-right-icon", v: MouseEvent): void;
  (e: "start-validate"): void;
  (e: "end-validate", v: { status: string; message: string }): void;
}>();
const VanFieldRef = ref();
function focus() {
  VanFieldRef.value?.focus();
}
function blur() {
  VanFieldRef.value?.blur();
}
const $props = computed<any>(() =>
  filterObject(omit(props, ["border", "type"]))
);
const eye = ref(false);
const type = computed(() => {
  if (props.type !== "password") return props.type;
  return eye.value ? "text" : "password";
});
defineExpose({ blur, focus });
// const slots = useSlots();
const slots = defineSlots<{
  label?: (props: {}) => any;
  input?: (props: {}) => any;
  button?: (props: {}) => any;
  extra?: (props: {}) => any;
  "left-icon"?: (props: {}) => any;
  "right-icon"?: (props: {}) => any;
  "error-message"?: (props: {}) => any;
}>();
const borderMode = computed(() => {
  const mode =
    typeof props.borderMode === "string"
      ? [props.borderMode]
      : props.borderMode;
  return mode?.map((v) => "Rinput__border-" + v);
});
</script>
<template>
  <van-field
    ref="VanFieldRef"
    class="Rinput"
    :class="borderMode"
    v-bind="{ ...$attrs, ...$props }"
    :type="type"
    :style="{
      '--Rinput-borderColor': props.borderColor,
      '--Rinput-borderStyle': props.borderStyle,
      '--Rinput-borderWidth': props.borderWidth,
    }"
    :border="false"
    @update:model-value="(e) => emit('update:model-value', e)"
    @focus="(e) => emit('focus', e)"
    @blur="(e) => emit('blur', e)"
    @clear="(e) => emit('clear', e)"
    @click="(e) => emit('click', e)"
    @click-input="(e) => emit('click-input', e)"
    @click-left-icon="(e) => emit('click-left-icon', e)"
    @click-right-icon="(e) => emit('click-right-icon', e)"
    @start-validate="emit('start-validate')"
    @end-validate="(e) => emit('end-validate', e)"
  >
    <!-- <template v-if="slots['label']" #label>
      <slot name="label"></slot>
    </template>
    <template v-if="slots['input']" #input>
      <slot name="input"></slot>
    </template>
    <template v-if="slots['left-icon']" #left-icon>
      <slot name="left-icon"></slot>
    </template>
    <template v-if="slots['right-icon']" #right-icon>
      <slot name="right-icon"></slot>
    </template>
    <template v-if="slots['button']" #button>
      <slot name="button"></slot>
    </template>
    <template v-if="slots['error-message']" #error-message="slotProps">
      <slot name="error-message" v-on="slotProps"></slot>
    </template>
    <template v-if="slots['extra']" #extra>
      <slot name="extra"></slot>
    </template> -->
    <template #[name]="slotProps" v-for="(slotItem, name) in slots">
      <slot :name="name" :="{ ...slotProps }"> </slot>
    </template>
    <template #button>
      <slot name="button">
        <van-icon
          @click="eye = !eye"
          v-if="!slots.button && props.type === 'password'"
          :name="eye ? 'eye-o' : 'closed-eye'"
        />
      </slot>
    </template>
  </van-field>
</template>
<style lang="scss" scoped>
.Rinput {
  --borderValue: var(--Rinput-borderStyle) var(--Rinput-borderColor)
    var(--Rinput-borderWidth);
}

.Rinput__border-all {
  border: var(--borderValue);
  padding: var(--gap-xs) var(--gap-sm);
}
.Rinput__border-left {
  border-left: var(--borderValue);
  padding: var(--gap-xs) var(--gap-sm);
}
.Rinput__border-right {
  border-right: var(--borderValue);
  padding: var(--gap-xs) var(--gap-sm);
}
.Rinput__border-top {
  border-top: var(--borderValue);
  padding: var(--gap-sm) 0;
}
.Rinput__border-bottom {
  border-bottom: var(--borderValue);
  padding: var(--gap-sm) 0;
}
.Rinput__border-none {
  padding: var(--gap-sm) 0;
}
</style>
